<!DOCTYPE html>
<html lang="zh-CN">





<head>
  <meta charset="UTF-8">
  <link rel="apple-touch-icon" sizes="76x76" href="/myblog/img/apple-touch-icon.png">
  <link rel="icon" type="image/png" href="/myblog/img/favicon.png">
  <meta name="viewport"
        content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, shrink-to-fit=no">
  <meta http-equiv="x-ua-compatible" content="ie=edge">
  
  <meta name="theme-color" content="#2f4154">
  <meta name="description" content="TakCode Blog">
  <meta name="author" content="谢芃">
  <meta name="keywords" content="">
  <title>前端面试 - TakCode</title>

  <link  rel="stylesheet" href="https://cdn.staticfile.org/font-awesome/5.12.1/css/all.min.css" />
<link  rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/4.4.1/css/bootstrap.min.css" />
<link  rel="stylesheet" href="https://cdn.staticfile.org/mdbootstrap/4.13.0/css/mdb.min.css" />
<link  rel="stylesheet" href="https://cdn.staticfile.org/github-markdown-css/3.0.1/github-markdown.min.css" />

<link rel="stylesheet" href="//at.alicdn.com/t/font_1067060_qzomjdt8bmp.css">



  <link  rel="stylesheet" href="/myblog/lib/prettify/tomorrow-night-eighties.min.css" />

<link  rel="stylesheet" href="/myblog/css/main.css" />


  <link defer rel="stylesheet" href="https://cdn.staticfile.org/fancybox/3.5.7/jquery.fancybox.min.css" />


<!-- 自定义样式保持在最底部 -->


<meta name="generator" content="Hexo 4.2.0"></head>


<body>
  <header style="height: 70vh;">
    <nav id="navbar" class="navbar fixed-top  navbar-expand-lg navbar-dark scrolling-navbar">
  <div class="container">
    <a class="navbar-brand"
       href="/myblog/">&nbsp;<strong>TakCode</strong>&nbsp;</a>

    <button id="navbar-toggler-btn" class="navbar-toggler" type="button" data-toggle="collapse"
            data-target="#navbarSupportedContent"
            aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
      <div class="animated-icon"><span></span><span></span><span></span></div>
    </button>

    <!-- Collapsible content -->
    <div class="collapse navbar-collapse" id="navbarSupportedContent">
      <ul class="navbar-nav ml-auto text-center">
        
          
          
          
          
          <li class="nav-item">
            <a class="nav-link" href="/myblog/">首页</a>
          </li>
        
          
          
          
          
          <li class="nav-item">
            <a class="nav-link" href="/myblog/archives/">归档</a>
          </li>
        
          
          
          
          
          <li class="nav-item">
            <a class="nav-link" href="/myblog/categories/">分类</a>
          </li>
        
          
          
          
          
          <li class="nav-item">
            <a class="nav-link" href="/myblog/tags/">标签</a>
          </li>
        
          
          
          
          
          <li class="nav-item">
            <a class="nav-link" href="/myblog/about/">关于</a>
          </li>
        
        
          <li class="nav-item" id="search-btn">
            <a class="nav-link" data-toggle="modal" data-target="#modalSearch">&nbsp;&nbsp;<i
                class="iconfont icon-search"></i>&nbsp;&nbsp;</a>
          </li>
        
      </ul>
    </div>
  </div>
</nav>

    <div class="view intro-2" id="background" parallax=true
         style="background: url('/myblog/img/default.png') no-repeat center center;
           background-size: cover;">
      <div class="full-bg-img">
        <div class="mask rgba-black-light flex-center">
          <div class="container text-center white-text fadeInUp">
            <span class="h2" id="subtitle">
              
            </span>

            
              
                <p class="mt-3 post-meta">
                  <i class="fas fa-calendar-alt" aria-hidden="true"></i>
                  星期日, 五月 5日 2019, 11:12 晚上
                </p>
              

              <p class="mt-1">
                
                  
                  <span class="post-meta">
                    <i class="far fa-chart-bar"></i>
                    4.1k 字
                  </span>
                

                
                  
                  <span class="post-meta">
                      <i class="far fa-clock"></i>
                      19 分钟
                  </span>
                

                
              </p>
            
          </div>

          
        </div>
      </div>
    </div>
  </header>

  <main>
    
      

<div class="container-fluid">
  <div class="row">
    <div class="d-none d-lg-block col-lg-2"></div>
    <div class="col-lg-8 nopadding-md">
      <div class="container nopadding-md" id="board-ctn">
        <div class="py-5 z-depth-3" id="board">
          <div class="post-content mx-auto" id="post">
            
            <div class="markdown-body">
              <p>前端面试</p>
<a id="more"></a>
<p>前端面试常用知识点</p>
<h1 id="CSS篇"><a href="#CSS篇" class="headerlink" title="CSS篇"></a>CSS篇</h1><h3 id="盒子水平垂直居中"><a href="#盒子水平垂直居中" class="headerlink" title="盒子水平垂直居中"></a>盒子水平垂直居中</h3><h4 id="方法1：定位"><a href="#方法1：定位" class="headerlink" title="方法1：定位"></a>方法1：定位</h4><pre><code class="html">&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&gt;
  &lt;head&gt;
    &lt;meta charset=&quot;UTF-8&quot; /&gt;
    &lt;title&gt;Document&lt;/title&gt;
    &lt;style&gt;
      html,
      body {
        height: 100%;
        overflow: hidden;
      }

      .box {
        box-sizing: border-box;
        width: 100px;
        height: 50px;
        line-height: 48px;
        text-align: center;
        font-size: 16px;
        border: 1px solid lightblue;
        background: lightcyan;
      }
      body {
        position: relative;
      }
      /* 定位1 需要考虑宽高 */
      .box {
        position: absolute;
        left: 50%;
        top: 50%;
        margin-top: -25px;
        margin-left: -50px;
      }
      /* 定位2 不考虑宽高，但一定要有宽高 */
      .box {
        position: absolute;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
      }
      /* 定位3 使用transform 兼容性一般 */
      .box {
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
      }
    &lt;/style&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;div class=&quot;box&quot;&gt;
      CSS篇
    &lt;/div&gt;
  &lt;/body&gt;
&lt;/html&gt;
</code></pre>
<h4 id="方法2：flex"><a href="#方法2：flex" class="headerlink" title="方法2：flex"></a>方法2：flex</h4><pre><code class="html">&lt;style&gt;
      html,
      body {
        height: 100%;
        overflow: hidden;
      }
      .box {
        box-sizing: border-box;
        width: 100px;
        height: 50px;
        line-height: 48px;
        text-align: center;
        font-size: 16px;
        border: 1px solid lightblue;
        background: lightcyan;
      }

      body {
        display: flex;
        justify-content: center;
        align-items: center;
      }
    &lt;/style&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;div class=&quot;box&quot;&gt;
      CSS篇
    &lt;/div&gt;
  &lt;/body&gt;</code></pre>
<h4 id="方法3：JavaScript"><a href="#方法3：JavaScript" class="headerlink" title="方法3：JavaScript"></a>方法3：JavaScript</h4><pre><code class="html">&lt;style&gt;
      html,
      body {
        height: 100%;
        overflow: hidden;
        position: relative;
      }
      .box {
        box-sizing: border-box;
        width: 100px;
        height: 50px;
        line-height: 48px;
        text-align: center;
        font-size: 16px;
        border: 1px solid lightblue;
        background: lightcyan;
      }
    &lt;/style&gt;

  &lt;body&gt;
    &lt;div class=&quot;box&quot; id=&quot;box&quot;&gt;
      CSS篇
    &lt;/div&gt;
    &lt;script&gt;
      let HTML = document.documentElement,
        winW = HTML.clientWidth,
        winH = HTML.clientHeight,
        boxW = box.offsetWidth,
        boxH = box.offsetHeight;
      box.style.position = &quot;absolute&quot;;
      box.style.left = (winW - boxW) / 2 + &quot;px&quot;;
      box.style.top = (winH - boxH) / 2 + &quot;px&quot;;
    &lt;/script&gt;
  &lt;/body&gt;</code></pre>
<h4 id="方法4：-display-table-cell"><a href="#方法4：-display-table-cell" class="headerlink" title="方法4： display: table-cell"></a>方法4： display: table-cell</h4><pre><code class="html">// 父级需要有宽高
&lt;style&gt;
      html,
      body {
        height: 100%;
        overflow: hidden;
      }
      .box {
        box-sizing: border-box;
        width: 100px;
        height: 50px;
        line-height: 48px;
        text-align: center;
        font-size: 16px;
        border: 1px solid lightblue;
        background: lightcyan;
      }
      .father {
        display: table-cell;
        vertical-align: middle;
        text-align: center;
        height: 500px;
        width: 500px;
        background-color: lightgrey;
      }
      .box {
        display: inline-block;
      }
    &lt;/style&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;div class=&quot;father&quot;&gt;
      &lt;div class=&quot;box&quot; id=&quot;box&quot;&gt;
        CSS篇
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/body&gt;</code></pre>
<h3 id="CSS盒模型"><a href="#CSS盒模型" class="headerlink" title="CSS盒模型"></a>CSS盒模型</h3><p>标准盒模型：</p>
<p>IE盒模型 box-sizing: border-box</p>
<p>Flex弹性盒模型</p>
<p><img src="http://www.ruanyifeng.com/blogimg/asset/2015/bg2015071004.png" srcset="/myblog/img/loading.gif" alt=""></p>
<h3 id="左右固定，中间自适应"><a href="#左右固定，中间自适应" class="headerlink" title="左右固定，中间自适应"></a>左右固定，中间自适应</h3><h4 id="圣杯布局"><a href="#圣杯布局" class="headerlink" title="圣杯布局"></a>圣杯布局</h4><pre><code class="html">    &lt;style&gt;
      html,
      body {
        height: 100%;
        overflow: hidden;
      }
      .container {
        height: 100%;
        padding: 0 200px;
      }
      .left,
      .right {
        width: 200px;
        min-height: 200px;
        background-color: lightblue;
      }
      .center {
        width: 100%;
        min-height: 400px;
        background-color: lightsalmon;
      }
      .left,
      .center,
      .right {
        float: left;
      }
      .left {
        margin-left: -100%;
        position: relative;
        left: -200px;
      }
      .right {
        margin-right: -200px;
      }
    &lt;/style&gt;

  &lt;body&gt;
    &lt;div class=&quot;container clearfix&quot;&gt;
      &lt;div class=&quot;center&quot;&gt;&lt;/div&gt;
      &lt;div class=&quot;left&quot;&gt;&lt;/div&gt;
      &lt;div class=&quot;right&quot;&gt;&lt;/div&gt;
    &lt;/div&gt;
  &lt;/body&gt;</code></pre>
<h4 id="双飞翼布局"><a href="#双飞翼布局" class="headerlink" title="双飞翼布局"></a>双飞翼布局</h4><pre><code class="html">&lt;style&gt;
      html,
      body {
        height: 100%;
        overflow: hidden;
      }
      .container,
      .left,
      .right {
        float: left;
      }
      .container {
        width: 100%;
      }
      .container .center {
        margin: 0 200px;
        min-height: 400px;
        background-color: lightsalmon;
      }
      .left,
      .right {
        width: 200px;
        min-height: 200px;
        background-color: lightblue;
      }
      .left {
        margin-left: -100%;
      }
      .right {
        margin-left: -200px;
      }
    &lt;/style&gt;
  &lt;/head&gt;
  &lt;body class=&quot;clearfix&quot;&gt;
    &lt;div class=&quot;container&quot;&gt;
      &lt;div class=&quot;center&quot;&gt;&lt;/div&gt;
    &lt;/div&gt;
    &lt;div class=&quot;left&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;right&quot;&gt;&lt;/div&gt;
  &lt;/body&gt;</code></pre>
<h4 id="flex"><a href="#flex" class="headerlink" title="flex"></a>flex</h4><pre><code class="html"> &lt;style&gt;
      html,
      body {
        height: 100%;
        overflow: hidden;
      }
      .container {
        display: flex;
        justify-content: space-between;
        height: 100%;
      }
      .left,
      .right {
        flex: 0 0 200px;
        height: 200px;
        background-color: lightblue;
      }
      .center {
        flex: 1;
        min-height: 400px;
        background-color: lightsalmon;
      }
    &lt;/style&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;div class=&quot;container&quot;&gt;
      &lt;div class=&quot;left&quot;&gt;&lt;/div&gt;
      &lt;div class=&quot;center&quot;&gt;&lt;/div&gt;
      &lt;div class=&quot;right&quot;&gt;&lt;/div&gt;
    &lt;/div&gt;
  &lt;/body&gt;</code></pre>
<h4 id="定位"><a href="#定位" class="headerlink" title="定位"></a>定位</h4><pre><code class="html">&lt;style&gt;
  html,
  body {
    height: 100%;
    overflow: hidden;
  }
  .container {
    position: relative;
    height: 100%;
  }
  .left,
  .right {
    position: absolute;
    top: 0;
    width: 200px;
    min-height: 200px;
    background-color: lightblue;
  }
  .left{
    left: 0
  }
  .right{
    right: 0
  }
  .center {
    margin: 0 200px;
    min-height: 400px;
    background-color: lightsalmon;
  }
&lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
  &lt;div class=&quot;container&quot;&gt;
    &lt;div class=&quot;left&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;center&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;right&quot;&gt;&lt;/div&gt;
  &lt;/div&gt;
&lt;/body&gt;</code></pre>
<h3 id="移动端响应式布局开发方案"><a href="#移动端响应式布局开发方案" class="headerlink" title="移动端响应式布局开发方案"></a>移动端响应式布局开发方案</h3><p>media, rem, flex, vh/vw </p>
<h1 id="JS篇"><a href="#JS篇" class="headerlink" title="JS篇"></a>JS篇</h1><h3 id="typeof-能判断的类型"><a href="#typeof-能判断的类型" class="headerlink" title="typeof 能判断的类型"></a>typeof 能判断的类型</h3><p>考点：js变量类型</p>
<p>typeof 能识别所有的值类型、识别函数、判断是否是引用类型（object）</p>
<h3 id="与-的使用方法"><a href="#与-的使用方法" class="headerlink" title="=== 与 ==的使用方法"></a>=== 与 ==的使用方法</h3><p>考点：强制类型转换</p>
<pre><code class="js">100 == &#39;100&#39; //true
0 == &#39;&#39; // true
0 == false // true
false == &#39;&#39; //ture
null == undefined // true

// 除了 == null 之外，其他都一律用===
if (obj.a == null)
// 相当于
if (obj.a ===  null || obj.a === undefined)</code></pre>
<h3 id="falsely变量和truly变量"><a href="#falsely变量和truly变量" class="headerlink" title="falsely变量和truly变量"></a>falsely变量和truly变量</h3><pre><code class="js">//以下是falsely变量，除此之外都是truly变量， !! 表示再次取反
!!0 === false
!!NaN === false
!!&#39;&#39; === false
!!null === false
!!undefined === false
!!false === false</code></pre>
<h3 id="值类型和引用类型的区别"><a href="#值类型和引用类型的区别" class="headerlink" title="值类型和引用类型的区别"></a>值类型和引用类型的区别</h3><pre><code class="js">常见值类型：undefined string number boolean symbol
//值类型
let a = 1000
let b = a
a = 200
console.log(b) //1000</code></pre>
<pre><code class="js">常见引用类型： object array null(指向空地址) function
// 引用类型
let a = {age: 20}
let b = a
b.age = 21
console.log(a.age) // 21
// b 指向的是a的内存地址</code></pre>
<p>值类型的值在栈上存储， 传递的是值 </p>
<p>引用类型的值在堆上存储,地址在栈上存储， 传递的是地址 </p>
<h3 id="手写深拷贝"><a href="#手写深拷贝" class="headerlink" title="手写深拷贝"></a>手写深拷贝</h3><pre><code class="js">const obj1 = {age:20,
              name:&#39;xiepeng&#39;,
              address:{city:&#39;beijing&#39;},
              arr:[&#39;a&#39;,&#39;b&#39;,&#39;c&#39;]
             }
const obj2 = obj1
obj2.address.city = &#39;guanzou&#39;
console.log(obj1.address.city) // guanzou 浅拷贝

const obj3 = deepClone(obj1)
obj3.arr[0] = &#39;aaa&#39;
console.log(obj1.arr[0])

function deepClone(obj = {}) {
  if (typeof obj !== &#39;object&#39; || obj == null) {
    return obj //obj为null,或者不是对象各数组时，直接返回
  }
  // 初始化返回结果
  let result 
  if (obj instanceof Array) { 
    //instanceof 用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上
    result = []
  } else {
    result = {}
  }
  for (let key in obj) {
    // 使用hasOwnProperty 保证key 不是原型的属性
    if (obj.hasOwnProperty(key)) {
      // 递归调用
      result[key] = deepClone(obj[key])
    }
  }
  // 返回结果
  return result
}</code></pre>
<h3 id="window-onload-和-DOMContentLoaded区别"><a href="#window-onload-和-DOMContentLoaded区别" class="headerlink" title="window.onload 和 DOMContentLoaded区别"></a>window.onload 和 DOMContentLoaded区别</h3><p>考点：页面加载过程</p>
<h3 id="JS创建10-lt-a-gt-标签，点击弹出对应的序号"><a href="#JS创建10-lt-a-gt-标签，点击弹出对应的序号" class="headerlink" title="JS创建10 &lt;a&gt; 标签，点击弹出对应的序号"></a>JS创建10 <code>&lt;a&gt;</code> 标签，点击弹出对应的序号</h3><p>考点：JS作用域 </p>
<pre><code class="js">let a
for (let i = 0; i&lt;10; i++) {
  a = document.createElement(&#39;a&#39;) // 这样写会存在DOM性能问题
  a.innerHTML = i + &#39;&lt;br /&gt;&#39;
  a.addEventListener(&#39;click&#39;,function(e) {
    e.preventDefault()
    alert(i)
  })
  document.body.appendChild(a)
}</code></pre>
<h3 id="手写节流throttle和防抖debounce"><a href="#手写节流throttle和防抖debounce" class="headerlink" title="手写节流throttle和防抖debounce"></a>手写节流throttle和防抖debounce</h3><p>考点：性能、体验优化</p>
<h3 id="Promise"><a href="#Promise" class="headerlink" title="Promise"></a>Promise</h3><p>Promise解决了回调地狱(callback hell)的问题</p>
<pre><code class="js">function loadimg(src) { // 常见的图片加载
  const p = new Promise(
    (resolve,reject) =&gt; {
      const img = document.createElement(&#39;img&#39;)
      img.onload = () =&gt; {
        resolve(img)
      }
      img.onerror = () =&gt; {
        const err = new Error(`图片加载失败${src}`)
        reject(err)
      }
      img.src = src
    }
  )
  return p
}
const url = &#39;http://helloxx.cn/CSS%E6%80%9D%E7%BB%B4%E5%AF%BC%E5%9B%BE.svg&#39;
loadimg(url).then(img =&gt; {
  console.log(img.width)
  return img
}).then(img =&gt; {
  console.log(img.height)
}).catch(ex =&gt; console.error(ex))</code></pre>
<h3 id="原型和原型链"><a href="#原型和原型链" class="headerlink" title="原型和原型链"></a>原型和原型链</h3><p>JS是基于原型的编程语言</p>
<p>每个构造函数都有显示原型prototype，每个实例都有隐式原型 <code>__proto__</code>，实例的 <code>__proto__</code>指向对应构造函数的prototype</p>
<p><img src="http://helloxx.cn/jd2img5.png" srcset="/myblog/img/loading.gif" alt=""></p>
<h3 id="如何准确判断一个变量是不是数组？"><a href="#如何准确判断一个变量是不是数组？" class="headerlink" title="如何准确判断一个变量是不是数组？"></a>如何准确判断一个变量是不是数组？</h3><pre><code class="js">let a = []
console.log(a instanceof Array) // true
console.log(a instanceof Object) // true</code></pre>
<h3 id="闭包"><a href="#闭包" class="headerlink" title="闭包"></a>闭包</h3><pre><code class="js">// 函数作为返回值
function create() {
  const a = 100
  return function() {
    console.log(a)
  }
}
const fn = create()
const a = 200
fn() // 100
//-----------------------
// 函数作为参数被传递 
function print(fn) {
  const a = 200
  fn()
}
const a = 100
function fn() {
  console.log(a)
}
print(fn) // 100</code></pre>
<p>结论：所有的自由变量的查找，是在函数定义的地方，向上级作用域查找，不是在执行的地方。</p>
<p>闭包的注意事项：通常，函数的作用域及其所有变量都会在函数执行结束后被销毁。但是，在创建了一个闭包以后，这个函数的作用域就会一直保存到闭包不存在为止。 </p>
<p> 应用闭包的主要场合是：设计私有的方法和变量。  任何在函数中定义的变量，都可以认为是私有变量，因为不能在函数外部访问这些变量。私有变量包括函数的参数、局部变量和函数内定义的其他函数。 </p>
<p>闭包的缺陷</p>
<ul>
<li>闭包的缺点就是常驻内存会增大内存使用量，并且使用不当很容易造成内存泄露。</li>
<li>如果不是因为某些特殊任务而需要闭包，在没有必要的情况下，在其它函数中创建函数是不明智的，因为闭包对脚本性能具有负面影响，包括处理速度和内存消耗。</li>
</ul>
<h3 id="this指向"><a href="#this指向" class="headerlink" title="this指向"></a>this指向</h3><pre><code class="js">const zhangsan = {
  name: &#39;张三&#39;,
  sayHi() {
    // this即当前对象
    console.log(this)
  },
  wait() {
    setTimeout(function() {
      // this === window
      console.log(this)
    })
  }
}
// ----------------
const zhangsan = {
  name: &#39;张三&#39;,
  sayHi() {
    // this即当前对象
    console.log(this)
  },
  wait() {
    setTimeout(() =&gt; {
      // this即当前对象
      console.log(this)  // 箭头函数中的作用域的 this 指向谁，它就指向谁
    })
  }
}</code></pre>
<h3 id="手写轮播"><a href="#手写轮播" class="headerlink" title="手写轮播"></a>手写轮播</h3><pre><code class="html">
&lt;html lang=&quot;zh&quot;&gt;
  &lt;head&gt;
    &lt;meta charset=&quot;UTF-8&quot;&gt;
    &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;
    &lt;meta http-equiv=&quot;X-UA-Compatible&quot; content=&quot;ie=edge&quot;&gt;
    &lt;title&gt;&lt;/title&gt;
    &lt;style type=&quot;text/css&quot;&gt;
      *{
        margin: 0;
        padding: 0;
      }
      li{
        list-style: none;
      }
      .wrap {
        width: 500px;
        height: 300px;
        position: relative;
      }
      .list {
        height: 100%;
        width: 100%;
      }
      .item{
        position: absolute;
        width: 100%;
        height: 100%;
        font-size: 60px;
        color: white;
        opacity: 0;
        transition: all 1s;
      }
      .item:nth-child(1) {
        background-color: red;
      }
      .item:nth-child(2) {
        background-color: chocolate;
      }
      .item:nth-child(3) {
        background-color: seagreen;
      }
      .item:nth-child(4) {
        background-color: cadetblue;
      }
      .item:nth-child(5) {
        background-color: mediumorchid;
      }
      .item.active{
        z-index: 10;
        opacity: 1;
      }
      .go{
        position: absolute;
        width: 30px;
        height: 50px;
        z-index: 100;
        top: 125px;
      }
      .right {
        right: 0;
      }
      .left {
        left: 0;
      }
      .pointList{
        height: 30px;
        position: absolute;
        bottom: -10px;
        z-index: 100;
        right: 200px;
      }
      .point{
        width: 10px;
        height: 10px;
        background-color: black;
        float: left;
        border-radius: 50%;
        margin: auto 5px;
      }
      .point.active{
        background-color: #CCCCCC;
      }
    &lt;/style&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;div class=&quot;wrap&quot;&gt;
      &lt;ul class=&quot;list&quot;&gt;
        &lt;li class=&quot;item active&quot;&gt;1&lt;/li&gt;
        &lt;li class=&quot;item&quot;&gt;2&lt;/li&gt;
        &lt;li class=&quot;item&quot;&gt;3&lt;/li&gt;
        &lt;li class=&quot;item&quot;&gt;4&lt;/li&gt;
        &lt;li class=&quot;item&quot;&gt;5&lt;/li&gt;
      &lt;/ul&gt;
      &lt;button class=&quot;go right&quot; type=&quot;button&quot;&gt;&gt;&lt;/button&gt;
      &lt;button class=&quot;go left&quot; type=&quot;button&quot;&gt;&lt;&lt;/button&gt;
        &lt;ul class=&quot;pointList&quot;&gt;
          &lt;li class=&quot;point active&quot; data-index=&quot;0&quot;&gt;&lt;/li&gt;
          &lt;li class=&quot;point&quot; data-index=&quot;1&quot;&gt;&lt;/li&gt;
          &lt;li class=&quot;point&quot; data-index=&quot;2&quot;&gt;&lt;/li&gt;
          &lt;li class=&quot;point&quot; data-index=&quot;3&quot;&gt;&lt;/li&gt;
          &lt;li class=&quot;point&quot; data-index=&quot;4&quot;&gt;&lt;/li&gt;
        &lt;/ul&gt;
        &lt;/div&gt;
      &lt;/body&gt;
    &lt;script type=&quot;text/javascript&quot;&gt;
      var li = document.querySelectorAll(&#39;.item&#39;) // 所有轮播图
      var points = document.querySelectorAll(&#39;.point&#39;) // 下方小圆点
      var btnR = document.querySelector(&#39;.right&#39;) // 下一个按钮
      var btnL = document.querySelector(&#39;.left&#39;) // 上一个按钮
      var index = 0 // 表示图片显示索引
      var time = 0 // 定时器图片跳转
      var clearActive = function() { // 清除样式
        for (var i = 0; i &lt; li.length; i++){
          li[i].className = &#39;item&#39;
          points[i].className = &#39;point&#39;
        }
      }
      var goIndex = function() {
        clearActive()
        li[index].className = &#39;item active&#39;
        points[index].className = &#39;point active&#39;
      }
      var goNext = function() {
        if(index &lt; li.length-1){
          index++
        }else{
          index = 0
        }
        goIndex()
      }
      var goLast = function() {
        if(index === 0){
          index = 4
        }else{
          index--
        }
        goIndex()
      }
      btnR.addEventListener(&#39;click&#39;,function(){
        goNext()
      })
      btnL.addEventListener(&#39;click&#39;,function(){
        goLast()
      })
      for(var i = 0; i &lt; points.length; i++) {
        points[i].addEventListener(&#39;click&#39;,function() {
          console.log(this.getAttribute(&#39;data-index&#39;))
          index = this.getAttribute(&#39;data-index&#39;)
          goIndex()
          time = 0
        })
      }
      setInterval(function(){ // 自动轮播定时器
        time++
        if(time == 20){
          goNext()
          time = 0
        }
      }, 200)
    &lt;/script&gt;
    &lt;/html&gt;</code></pre>
<h3 id="手写-bind"><a href="#手写-bind" class="headerlink" title="手写 bind"></a>手写 bind</h3><h3 id="class-的原型本质"><a href="#class-的原型本质" class="headerlink" title="class 的原型本质"></a>class 的原型本质</h3><p>class 只是一个语法糖，本质还是函数， class 实现继承的核心在于使用 extends 表明继承来自哪个父类， 子类使用 super 关键字访问父类的方法 </p>
<h3 id="异步和单线程"><a href="#异步和单线程" class="headerlink" title="异步和单线程"></a>异步和单线程</h3><p>JS是单线程语言，只能同时做一件事，JS 和 DOM 渲染共用同一个线程，因为JS可修改 DOM 结构</p>
<p>遇到等待（网络请求，定时任务）不能卡住，所以出现了异步。异步是 callback 函数回调。</p>
<p><strong>同步和异步的区别是什么</strong>？</p>
<p>异步不会阻塞代码执行，同步会阻塞代码拣选</p>
<p><strong>前端使用异步的场景有哪些</strong>？</p>
<p>网络请求，如 Ajax 图片加载，定时任务，如 setTimeout</p>
<h3 id="DOM"><a href="#DOM" class="headerlink" title="DOM"></a>DOM</h3><p>DOM是一种树形数据结构，DOM 操作是非常“昂贵”的，应该避免频繁的 DOM 操作，对 DOM 查询做缓存，将频繁操作改为一次性操作</p>
<pre><code class="js">// 不缓存 DOM 查询结果
for (let = 0; i &lt; document.getElementsByTagName(&#39;p&#39;).length; i++) {
  // 每次循环，都会计算 lenght ，频繁进行 DOM查询
}

// 缓存 DOM 查询结果
const pList = document.getElementByTagName(&#39;p&#39;)
const pLen = pList.length
for (let i = 0; i &lt; pLen; i++) {
  // 缓存 lenght ，只进行一次 DOM查询
}</code></pre>
<p><strong>DOM操作的常用API</strong></p>
<pre><code class="js">// 获取 DOM 节点
const div1 = document.getElementById(&#39;div1&#39;) // 根据 id 来进行获取单个元素
const div2 = docment.querySelector(&#39;.child&#39;) // 根据 css 选择器来获取
const divList = document.getElementsByTagName(&#39;div&#39;) // 集合
const newP = document.createElement(&#39;p&#39;) // 新建节点
newP.innerHTML = &#39;this is newP&#39; // 添加内容
div1.appendChild(newP) // div1 中插入节点
const child = div1.childNodes // 获取子元素列表
const parent = div1.parentNode // 获取父元素
div1.removeChild(child[0]) // 删除节点
// property 操作形式
console.log(div2.style.width) // 对应标签的长度
console.log(div2.className) // 对应标签的 class 名称
// attribute 操作形式
div2.setAttribute(&#39;class&#39;, &#39;child&#39;) // 给对应标签加添 class
console.log(div2.getAttribute(&#39;class&#39;)) // child

/** attribute 和 property 的区别
property 是修改对象属性（DOM），不会体现到 html 结构中
attribute 是修改 html 属性，会改变 html 结构
html中自定义的属性，attribute 可以获取到，property 获取不到
两者都可能引起 DOM 重新渲染
在 javascript 中我们推荐使用 property 属性因为这个属性相对 attribute 更快，更简便。尤其是有些类型本该是布尔类型的 attribute 特性。比如：&quot;checked&quot;, &quot;disabled&quot;, &quot;selected&quot;。浏览器会自动将这些值转变成布尔值传给 property 属性。
**/</code></pre>
<p>一次性插入多个DOM节点，考虑性能</p>
<pre><code class="js">const listNode = document.getElementBtId(&#39;list&#39;)
// 创建一个文档片段，此时还没有插入到 DOM 树中
const frag = document.createDocumentFragment()
// 执行插入
for (let x = 0; x &lt; 10; x++) {
  const li = document.createElement(&#39;li&#39;)
  li.innerHTML = &#39;List item&#39; + x
  frag.appendChild(li)
}
// 再插入到 DOM    树中
listNode.appendChild(frag)</code></pre>
<h3 id="BOM"><a href="#BOM" class="headerlink" title="BOM"></a>BOM</h3><p>如何识别浏览器的类型</p>
<h3 id="事件"><a href="#事件" class="headerlink" title="事件"></a>事件</h3><p>编写一个通用的事件监听函数</p>
<pre><code></code></pre><h3 id="ajax"><a href="#ajax" class="headerlink" title="ajax"></a>ajax</h3><h3 id="什么是前端跨域？怎么解决前端跨域？"><a href="#什么是前端跨域？怎么解决前端跨域？" class="headerlink" title="什么是前端跨域？怎么解决前端跨域？"></a>什么是前端跨域？怎么解决前端跨域？</h3><p>跨域是浏览器为了安全而做出的限制策略，浏览器请求必须遵循同源策略：同域名、同端口、同协议</p>
<p>解决方案：</p>
<blockquote>
<p>CORS跨域：服务端设置，前端直接调用</p>
<p>JSONP跨域：前端适配（导入jsonp），请求的只是一段JS脚本，后台配合</p>
<p>代理跨域：通过修改nginx服务器配置来实现</p>
</blockquote>
<h3 id="Cookie、localStorage、sessionStorage三者的区别"><a href="#Cookie、localStorage、sessionStorage三者的区别" class="headerlink" title="Cookie、localStorage、sessionStorage三者的区别"></a>Cookie、localStorage、sessionStorage三者的区别</h3><p> webstorage是本地存储，存储在客户端，包括localStorage和sessionStorage。 </p>
<p> localStorage生命周期是永久，这意味着除非用户显示在浏览器提供的UI上清除localStorage信息，否则这些信息将永远存在。存放数据大小为一般为5MB,而且它仅在客户端（即浏览器）中保存，只存储在域名下，不参与和服务器的通信。 </p>
<p> sessionStorage仅在当前会话下有效，关闭页面或浏览器后被清除。存放数据大小为一般为5MB,而且它仅在客户端（即浏览器）中保存，只存储在域名下，不参与和服务器的通信。源生接口可以接受，亦可再次封装来对Object和Array有更好的支持。 </p>
<p> cookie可以在前后端进行用户的身份认证，标记用户 ，生命期为只在设置的cookie过期时间之前一直有效，即使窗口或浏览器关闭。 存放数据大小为4K左右 。有个数限制（各浏览器不同），一般不能超过20个。与服务器端通信：每次都会携带在HTTP头中，如果使用cookie保存过多数据会带来性能问题。 </p>
<p>localStorage、sessionStorage、Cookie共同点：都是保存在浏览器端，且同源的。</p>
<h3 id="为什么封装Storage？"><a href="#为什么封装Storage？" class="headerlink" title="为什么封装Storage？"></a>为什么封装Storage？</h3><p>Storage本身有api，但是只是简单的key/value形式</p>
<p>Storage只存储字符串，需要手动转换成json对象</p>
<p>Storage只能一次性清空，不能单个清空</p>
<pre><code class="js">/**
 * 封装Storage json形式
 */

const STORAGE_KEY = &#39;mall&#39;
export default {
  // 存储值
  setItem(key, value, moduleName) {
    if (moduleName) { // 存储层级下的数据
      const val = this.getItem(moduleName)
      val[key] = value
      this.setItem(moduleName, val)
    } else { // 存储到根部
      const val = this.getStorage()
      val[key] = value
      window.sessionStorage.setItem(STORAGE_KEY, JSON.stringify(val))
    }
  },
  // 获取值
  getItem(key, moduleName) {
    if (moduleName) {
      // 递归获取层级
      const val = this.getItem(moduleName)
      if (val) return val[key]
    }
    return this.getStorage()[key]
  },
  // 获取整个数据
  getStorage() {
    return JSON.parse(window.sessionStorage.getItem(STORAGE_KEY) || &#39;{}&#39;)
  },
  // 清空某一个值
  clear(key, moduleName) {
    const val = this.getStorage()
    if (moduleName) {
      if (!val[moduleName]) return
      delete val[moduleName][key]
    } else {
      delete val[key]
    }
    window.sessionStorage.setItem(STORAGE_KEY, JSON.stringify(val))
  }
}
</code></pre>
<p>接口错误拦截</p>
<h3 id="CSRF"><a href="#CSRF" class="headerlink" title="CSRF"></a>CSRF</h3><p>CSRF，通常称为跨站请求伪造，Cross-site request forgery</p>

            </div>
            <hr>
            <div>
              <p>
                
                
              </p>
              
                <p class="note note-warning">本博客所有文章除特别声明外，均采用 <a href="https://zh.wikipedia.org/wiki/Wikipedia:CC_BY-SA_3.0%E5%8D%8F%E8%AE%AE%E6%96%87%E6%9C%AC" target="_blank" rel="nofollow noopener noopener">CC BY-SA 3.0协议</a> 。转载请注明出处！</p>
              
              
                <div class="post-prevnext row">
                  <div class="post-prev col-6">
                    
                    
                      <a href="/myblog/2019/09/15/Nodejs+MongoDB%E7%AC%94%E8%AE%B0/">
                        <i class="fa fa-chevron-left"></i>
                        <span class="hidden-mobile">Node学习笔记</span>
                        <span class="visible-mobile">上一篇</span>
                      </a>
                    
                  </div>
                  <div class="post-next col-6">
                    
                    
                      <a href="/myblog/2019/05/05/Vue%E7%AC%94%E8%AE%B0/">
                        <span class="hidden-mobile">Vue学习笔记</span>
                        <span class="visible-mobile">下一篇</span>
                        <i class="fa fa-chevron-right"></i>
                      </a>
                    
                  </div>
                </div>
              
            </div>

              
          </div>
        </div>
      </div>
    </div>
    
      <div class="d-none d-lg-block col-lg-2 toc-container" id="toc-ctn">
        <div id="toc-start"></div>
<div id="toc">
  <p class="h5"><i class="far fa-list-alt"></i>&nbsp;目录</p>
  <div id="tocbot"></div>
</div>

      </div>
    
  </div>
</div>

<!-- Custom -->


    
  </main>

  
    <a class="z-depth-1" id="scroll-top-button" href="#" role="button">
      <i class="fa fa-chevron-up scroll-top-arrow" aria-hidden="true"></i>
    </a>
  

  
    <div class="modal fade" id="modalSearch" tabindex="-1" role="dialog" aria-labelledby="ModalLabel"
     aria-hidden="true">
  <div class="modal-dialog modal-dialog-scrollable modal-lg" role="document">
    <div class="modal-content">
      <div class="modal-header text-center">
        <h4 class="modal-title w-100 font-weight-bold">搜索</h4>
        <button type="button" id="local-search-close" class="close" data-dismiss="modal" aria-label="Close">
          <span aria-hidden="true">&times;</span>
        </button>
      </div>
      <div class="modal-body mx-3">
        <div class="md-form mb-5">
          <input type="text" id="local-search-input" class="form-control validate">
          <label data-error="x" data-success="v"
                 for="local-search-input">关键词</label>
        </div>
        <div class="list-group" id="local-search-result"></div>
      </div>
    </div>
  </div>
</div>
  

  

  

  <footer class="mt-5">
  <div class="text-center py-3">
    <div>
      <a href="https://hexo.io" target="_blank" rel="nofollow noopener"><b>Hexo</b></a>
      <i class="iconfont icon-love"></i>
      <a href="https://github.com/fluid-dev/hexo-theme-fluid" target="_blank" rel="nofollow noopener"> <b>Fluid</b></a>
    </div>
    

    

    
  </div>
</footer>

<!-- SCRIPTS -->
<script  src="https://cdn.staticfile.org/jquery/3.4.1/jquery.min.js" ></script>
<script  src="https://cdn.staticfile.org/popper.js/1.16.1/umd/popper.min.js" ></script>
<script  src="https://cdn.staticfile.org/twitter-bootstrap/4.4.1/js/bootstrap.min.js" ></script>
<script  src="https://cdn.staticfile.org/mdbootstrap/4.13.0/js/mdb.min.js" ></script>
<script  src="/myblog/js/main.js" ></script>


  <script  src="/myblog/js/lazyload.js" ></script>



  
  <script  src="https://cdn.staticfile.org/tocbot/4.10.0/tocbot.min.js" ></script>
  <script>
    $(document).ready(function () {
      var navHeight = $('#navbar').height();
      var toc = $('#toc');
      var boardCtn = $('#board-ctn');
      var boardTop = boardCtn.offset().top;
      var tocLimMax = 2 * boardTop + boardCtn.height();

      $(window).scroll(function () {
        var tocLimMin = $('#toc-start').offset().top - navHeight;
        var scroH = document.body.scrollTop + document.documentElement.scrollTop;

        if (tocLimMin <= scroH && scroH <= tocLimMax) {
          toc.css({
            'display': 'block',
            'position': 'fixed',
            'top': navHeight,
          });
        } else if (scroH <= tocLimMin) {
          toc.css({
            'position': '',
            'top': '',
          });
        } else if (scroH > tocLimMax) {
          toc.css('display', 'none');
        }
      });
      tocbot.init({
        tocSelector: '#tocbot',
        contentSelector: '.post-content',
        headingSelector: 'h1,h2,h3,h4,h5,h6',
        linkClass: 'tocbot-link',
        activeLinkClass: 'tocbot-active-link',
        listClass: 'tocbot-list',
        isCollapsedClass: 'tocbot-is-collapsed',
        collapsibleClass: 'tocbot-is-collapsible',
        scrollSmooth: true,
        headingsOffset: -boardTop
      });
      if ($('.toc-list-item').length > 0) {
        $('#toc > p').css('visibility', 'visible');
      }
      var offset = boardCtn.css('margin-right')
      $('#toc-ctn').css({
        'right': offset
      })
    });
  </script>





  <script defer src="https://cdn.staticfile.org/clipboard.js/2.0.6/clipboard.min.js" ></script>
  <script  src="/myblog/js/clipboard-use.js" ></script>








<!-- Plugins -->



  <script  src="https://cdn.staticfile.org/prettify/188.0.0/prettify.min.js" ></script>
  <script>
    $(document).ready(function () {
      $('pre').addClass('prettyprint  linenums');
      prettyPrint();
    })
  </script>



  <script  src="https://cdn.staticfile.org/typed.js/2.0.11/typed.min.js" ></script>
  <script>
    var typed = new Typed('#subtitle', {
      strings: [
        '  ',
        "前端面试&nbsp;",
      ],
      cursorChar: "_",
      typeSpeed: 70,
      loop: false,
    });
    typed.stop();
    $(document).ready(function () {
      $(".typed-cursor").addClass("h2");
      typed.start();
    });
  </script>



  <script  src="https://cdn.staticfile.org/anchor-js/4.2.2/anchor.min.js" ></script>
  <script>
    anchors.options = {
      placement: "right",
      visible: "hover",
      
    };
    var el = "h1,h2,h3,h4,h5,h6".split(",");
    var res = [];
    for (item of el) {
      res.push(".markdown-body > " + item)
    }
    anchors.add(res.join(", "))
  </script>



  <script  src="/myblog/js/local-search.js" ></script>
  <script>
    var path = "/myblog/local-search.xml";
    var inputArea = document.querySelector("#local-search-input");
    inputArea.onclick = function () {
      getSearchFile(path);
      this.onclick = null
    }
  </script>



  <script defer src="https://cdn.staticfile.org/fancybox/3.5.7/jquery.fancybox.min.js" ></script>
  <script>
    $("#post img:not(.no-zoom img, img[no-zoom])").each(
      function () {
        var element = document.createElement("a");
        $(element).attr("data-fancybox", "images");
        $(element).attr("href", $(this).attr("src"));
        $(this).wrap(element);
      }
    );
  </script>












</body>
</html>
